<template>
  <el-dialog
    v-dialogDrag
    v-if="popenevTVisible"
    :visible.sync="popenevTVisible"
    :before-close="handleCancel"
    width="400px"
    :close-on-click-modal="true"
    :show-close="false"
  >
    <div class="alert-title-box" slot="title">
      <div class="alert-icon" :style="{ backgroundColor: iconBg }" v-if="icon">
        <i :class="icon" :style="{ color: iconColor, fontSize: iconSize }"></i>
      </div>
      <div class="hc-min-title alert-title">提示</div>
    </div>
    <div class="alert-close-icon" @click="btnHandle('closeAlert')">
      <i class="el-icon-close" style="font-size:20px;color:#fff"></i>
    </div>
    <div class="alert-wrap">
      <div v-show="!isShowInfo">
        <div v-if="content" class="hc-text alert-content" v-html="content? content.replace(/\n/g, '<br>') : content"></div>
      </div>
      <div v-show="isShowInfo">
        <div class="alert-error-message" v-html="contentInfo && contentInfo.replace(/\n/g, '<br>').replace(/\t/g, '&emsp;')"></div>
      </div>
      <div class="alert-feedback" v-if="showFeedback && isError">
        <el-button type="text" @click="feedbackHandle">反馈管理员</el-button>
      </div>
      <div class="alert-show-message">
        <el-button type="text" v-if="isHaveInfo && !isShowInfo" icon="el-icon-arrow-down" @click="handleShowErrorInfo"></el-button>
        <el-button type="text" v-if="isHaveInfo && isShowInfo" icon="el-icon-arrow-up" @click="isShowInfo = false"></el-button>
      </div>
      <div class="alert-footer" v-if="btnList.length > 0" :class="[btnList.length > 1? 'hc-justify-lr' : 'hc-justify-center']">
        <div v-for="(item, index) in btnList" :key="index">
          <el-button v-if="item.text" :type="item.type" :circle="item.circle" :plain="item.plain" :round="item.round" @click="btnHandle(item.event)">{{ item.text }}</el-button>
        </div>
      </div>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from 'vue';
import { createOrder } from "../../api/module/ywgl";
import errorCode from '../../utils/errorCode';
import { useRoute } from 'vue-router';
import { ElMessage, ElMessageBox } from 'element-plus';

// 响应式数据
const popenevTVisible = ref(false);
const closeTime = ref('-1');
const icon = ref('');
const iconColor = ref('');
const iconBg = ref('');
const iconSize = ref('');
const title = ref('');
const content = ref('');
const btnList = ref([]);
const isHaveInfo = ref(false);
const isShowInfo = ref(false);
const contentInfo = ref('');
const isConfirm = ref(false);
const timgerId = ref(null);
const isError = ref(false);
const isFeedback = ref(false);
const frontErrorUrl = ref('');
const backErrorUrl = ref('');
const showFeedback = ref(window.HC_config.VUE_SHOW_FEEDBACK);

const route = useRoute();

// 按钮点击处理
const btnHandle = (event) => {
  if (event === 'closeAlert') {
    if (isConfirm.value) {
      ElMessageBox.confirm('是否关闭提示', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        handleCancel();
      }).catch(() => { });
    } else {
      handleCancel();
    }
  } else if (event ==='sure') {
    handleOk();
  }
};

// 初始化数据
const initData = (showData) => {
  console.log(showData, "=======================showData");
  const type = showData.messageType;
  closeTime.value = showData.closeTime;
  if (closeTime.value!== '-1') {
    const _closeTime = Number(closeTime.value) || 2000;
    timgerId.value = setTimeout(() => {
      popenevTVisible.value = false;
      // 这里需要处理 promiseStatus.resolve，由于 setup 中不能直接使用 this，可通过回调函数传递 resolve
      promiseStatusResolve({ isNext: true });
    }, _closeTime);
  }
  const messageContent = showData.messageContent;
  icon.value = messageContent.icon || '';
  iconColor.value = messageContent.iconColor || 'white';
  iconBg.value = messageContent.iconBg || '';
  iconSize.value = messageContent.iconSize || '36px';
  title.value = messageContent.title || '';
  content.value = messageContent.content || '';
  if (type === "error") {
    filtrationError(content.value);
  }
  btnList.value = messageContent.btnList || [];
  const errData = showData.errData;
  if (errData) {
    frontErrorUrl.value = route.path;
    backErrorUrl.value = errData.backErrorUrl;
  }
  popenevTVisible.value = true;
  return new Promise((resolve) => {
    promiseStatusResolve = resolve;
  });
};

// 显示弹窗
const showModal = (showData, P_IsConfirm) => {
  isConfirm.value = P_IsConfirm || false;
  return initData(showData);
};

// 获取按钮样式
const getBtnStyle = (item) => {
  return item.style;
};

// 确定按钮处理
const handleOk = () => {
  promiseStatusResolve({ isNext: true });
};

// 取消按钮处理
const handleCancel = () => {
  promiseStatusReject({ msg: "取消" });
  destroyElement();
};

// 销毁组件
const destroyElement = () => {
  popenevTVisible.value = false;
  if (timgerId.value) {
    clearTimeout(timgerId.value);
  }
};

// 显示错误信息
const handleShowErrorInfo = () => {
  isShowInfo.value = true;
  if (timgerId.value) {
    clearTimeout(timgerId.value);
  }
};

// 对错误信息进行过滤
const filtrationError = (P_Content) => {
  if (P_Content === errorCode['default']) {
    isHaveInfo.value = true;
    contentInfo.value = "后端空指针异常";
    isError.value = true;
  }
  if (/[a-zA-Z]/.test(P_Content)) {
    content.value = detectErrorType(P_Content);
    isHaveInfo.value = true;
    contentInfo.value = P_Content;
    isError.value = true;
  } else {
    content.value = P_Content;
  }
  if (isError.value && isFeedback.value) { }
};

// 检测错误类型
const detectErrorType = (P_ErrorContent) => {
  const nullPointerExceptionRegex = /NullPointerException/;
  const classCastExceptionRegex = /ClassCastException/;
  const sqlErroRegex = /SQLException|bad SQL/;
  const arrayIndexOutOfBoundsRegex = /ArrayIndexOutOfBoundsException/;
  const NumberFormatExceptionRegex = /NumberFormatException/;
  const IllegalStateExceptionRegex = /IllegalStateException/;
  const IOExceptionRegex = /IOException/;
  if (nullPointerExceptionRegex.test(P_ErrorContent)) {
    return "空指针异常,请联系运维人员";
  } else if (classCastExceptionRegex.test(P_ErrorContent)) {
    return "类型转换异常,请联系运维人员";
  } else if (sqlErroRegex.test(P_ErrorContent)) {
    const columName = getMissColum(P_ErrorContent);
    if (columName) {
      return "SQL异常,缺少字段:" + columName + "。请联系运维人员";
    }
    const tableName = getMissTable(P_ErrorContent);
    if (tableName) {
      return "SQL异常,表:" + tableName + "不存在。请联系运维人员";
    }
    return "SQL异常,请联系运维人员";
  } else if (arrayIndexOutOfBoundsRegex.test(P_ErrorContent)) {
    return "数组越界,请联系运维人员";
  } else if (NumberFormatExceptionRegex.test(P_ErrorContent)) {
    return "数字转换异常,请联系运维人员";
  } else if (IllegalStateExceptionRegex.test(P_ErrorContent)) {
    return "非法状态异常,请联系运维人员";
  } else if (IOExceptionRegex.test(P_ErrorContent)) {
    return "文件读取或写入异常,请联系运维人员";
  } else {
    return "系统异常，请联系运维人员";
  }
};

// 获取缺少字段
const getMissColum = (P_Content) => {
  const regex = /Unknown column '([^']+)'/;
  const match = P_Content.match(regex);
  return match? match[1] : null;
};

// 获取缺少表
const getMissTable = (P_Content) => {
  const regex = /Table '([^']+\.[^']+)' doesn't exist/;
  const match = P_Content.match(regex);
  return match? match[1] : null;
};

const feedbackHandle = () => {
  ElMessage({
    message: '已反馈，请耐心等待',
    type:'success'
  });
  const errData = {
    errMsg: contentInfo.value,
    errUrl: frontErrorUrl.value,
    errPath: backErrorUrl.value,
    boolAutoSend: false,
  };
  createOrder(errData).then((res) => {
    if (res.code === 200) {
      isFeedback.value = true;
    }
  });
  destroyElement();
};

// 用于 resolve 和 reject 的函数，在 setup 中不能直接使用 this.promiseStatus
let promiseStatusResolve;
let promiseStatusReject;
</script>

<style lang="scss" scoped>
.alert-close-wrap {
  padding: 0 10px;
}

.alert-close-icon {
  position: absolute;
  right: -40px;
  top: -40px;
  cursor: pointer;
  width: 40px;
  height: 40px;
  line-height: 44px;
  border: 2px #ccc solid;
  text-align: center;
  border-radius: 50%;

  i {
    font-weight: 600;
    font-size: 26px!important;
  }
}

.alert-icon {
  border-radius: 50%;
}

.alert-header{
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.alert-title-box {
  display: flex;
  justify-content: flex-start;
  align-items: center;
 .alert-title {
    margin-left: 10px;
    font-weight: bold;
  }
}

.alert-wrap {
  padding: 10px 5px 0 5px;
  background: #fff;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  flex-wrap: nowrap;
  height: auto;
  width: 100%;
  border-radius: 6px;
  //padding-bottom: 20px;
  text-align: center;
  position: relative;

 .alert-content {
    width: 100%;
    margin: 10px 0;
    line-height: 28px;
    color: #0d0f33;
    text-align: center;
    margin-bottom: 40px;
    flex: 1;
    font-size: 18px;
  }

 .alert-error-message{
    text-align: left;
  }

 .alert-footer {
    // position: absolute;
    // bottom: 26px;
    width: 100%;
    height: 36px;
    display: flex;
    margin-top: 20px;

   .common-btn {
      width: 100px;
      height: 36px;
      line-height: 36px;
      text-align: center;
      border-radius: 4px;
      margin: 10px;
      cursor: pointer;
    }
  }

 .hc-justify-lr {
    justify-content: space-evenly;
  }

 .hc-justify-center {
    justify-content: center;
  }
}

.alert-feedback.el-button.el-button--text.el-button--medium,
.alert-show-message.el-button.el-button--text.el-button--medium{
  padding: 6px 20px;
}
</style>